package com.atguigu.tingshu.user.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.bson.types.ObjectId;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Override
    public BigDecimal getTrackBreakSecond(Long trackId) {
        //1、mongodb查询 用户的trackId的播放进度
        UserListenProcess userListenProcess = mongoTemplate.findOne(Query.query(
                Criteria.where("userId").is(AuthContextHolder.getUserId())
                        .and("trackId").is(trackId)
        ), UserListenProcess.class);

        //2、更新声音和专辑的播放量
        // 发送mq消息
        // 同一个用户 一个声音 一天只发送一个消息
        // redis的bitmap：  userId->bitmap( 使用声音id当作offset，设置为1表示已经发送过消息 )
        String key = RedisConstant.TRACK_STAT_IDEM +AuthContextHolder.getUserId();
        Boolean exists = redisTemplate.opsForValue().getBit(key, trackId);
        if(!exists){
            //不存在 发送消息
            redisTemplate.opsForValue().setBit(key , trackId , true);
//            new DateTime().withTimeAtStartOfDay()
            //到第二天的零点过期
            //joda-time: 工具包  专门用来处理时间日期
            redisTemplate.expire(key ,
                    new DateTime().plusDays(1).withTimeAtStartOfDay().toDate().getTime() -
                            System.currentTimeMillis(),  TimeUnit.MILLISECONDS);
            //发送mq消息 更新播放量
            //  trackId , albumId
            TrackStatMqVo vo = new TrackStatMqVo();
            vo.setTrackId(trackId);
//            vo.setAlbumId(vo.getAlbumId());
            vo.setBusinessNo(IdUtil.getSnowflakeNextIdStr());
            vo.setCount(1);
            vo.setStatType(SystemConstant.TRACK_STAT_PLAY);
            rabbitTemplate.convertAndSend(
                    RabbitConstant.ALBUM_EXCHANGE,
                    RabbitConstant.TRACK_STAT_RK,
                    vo
            );
        }

        return userListenProcess==null?new BigDecimal("0"):userListenProcess.getBreakSecond();
    }

//    public static void main(String[] args) {
//        System.out.println(System.currentTimeMillis());
//        System.out.println(new DateTime().plusDays(1).withTimeAtStartOfDay().toDate().getTime());
//    }
    @Override
    public void updateListenProcess(UserListenProcessVo vo) {
        UserListenProcess userListenProcess = mongoTemplate.findOne(Query.query(
                Criteria.where("userId").is(AuthContextHolder.getUserId())
                        .and("trackId").is(vo.getTrackId())
        ), UserListenProcess.class);
        //1、如果用户第一次播放提交声音的进度，新增
        if(userListenProcess==null){
            userListenProcess = new UserListenProcess();
            userListenProcess.setId(ObjectId.get().toString());
            userListenProcess.setUserId(AuthContextHolder.getUserId());
            userListenProcess.setAlbumId(vo.getAlbumId());
            userListenProcess.setTrackId(vo.getTrackId());
            userListenProcess.setIsShow(1);
            userListenProcess.setBreakSecond(vo.getBreakSecond());
            userListenProcess.setCreateTime(new Date());
            userListenProcess.setUpdateTime(new Date());
//            mongoTemplate.save(userListenProcess ,
//                    //参数2可以省略：
//                    MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS
//                             , AuthContextHolder.getUserId() ));
        }else{
            //2、更新
            userListenProcess.setBreakSecond(vo.getBreakSecond());
            userListenProcess.setUpdateTime(new Date());
        }
        mongoTemplate.save(userListenProcess);
    }

    @Override
    public JSONObject getLatelyTrack() {
        // ESTemplate:
        //查询 更新时间降序排列的第一条数据
        UserListenProcess listenProcess = mongoTemplate.findOne(Query.query(
                        Criteria.where("userId").is(AuthContextHolder.getUserId())
                ).with(Sort.by("updateTime").descending()
                ).with(Pageable.ofSize(1).withPage(0)),
                UserListenProcess.class);
        JSONObject jsonObject = new JSONObject();
        if(listenProcess==null){
            //使用推荐的声音：   可以调用推荐接口(根据用户的爱好推荐  或者广告)
            jsonObject.put("albumId","1466");
            jsonObject.put("trackId","49161");

        }else{
            //使用查询到的最近的播放记录
            jsonObject.put("albumId",listenProcess.getAlbumId());
            jsonObject.put("trackId",listenProcess.getTrackId());
        }
        return jsonObject;
    }
}
